package com.guiji.quartz.task;

import com.guiji.quartz.util.DingUtil;
import org.apache.http.HttpHost;
import org.apache.lucene.search.TotalHits;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;


/**
 * @program: cms-vue-plus
 * @description:
 * @author: wangxw
 * @create: 2021-12-14 15:05
 **/
@Component("systemCheckTask")
public class SystemCheckTask {
	private static final Logger log = LoggerFactory.getLogger(SystemCheckTask.class);
	public static String index = "metricbeat-*";
	private static final Double alarmRate = 0.8;

	@Autowired
	RestHighLevelClient restHighLevelClient;

	private static HttpHost[] getHttpHosts(String clientIps, int esHttpPort) {
		String[] clientIpList = clientIps.split(",");
		HttpHost[] httpHosts = new HttpHost[clientIpList.length];
		for (int i = 0; i < clientIpList.length; i++) {
			httpHosts[i] = new HttpHost(clientIpList[i], esHttpPort, "http");
		}
		return httpHosts;
	}

	private static String getUTC() {
		StringBuffer UTCTimeBuffer = new StringBuffer();
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.SECOND, -30);
		int zoneOffset = cal.get(java.util.Calendar.ZONE_OFFSET);
		int dstOffset = cal.get(java.util.Calendar.DST_OFFSET);
		cal.add(java.util.Calendar.MILLISECOND, -(zoneOffset + dstOffset));
		int year = cal.get(Calendar.YEAR);
		int month = cal.get(Calendar.MONTH) + 1;
		int day = cal.get(Calendar.DAY_OF_MONTH);
		int hour = cal.get(Calendar.HOUR_OF_DAY);
		String hourStr = hour < 10 ? new StringBuffer("0").append(hour).toString() : String.valueOf(hour);
		int minute = cal.get(Calendar.MINUTE);
		String minuteStr = minute < 10 ? new StringBuffer("0").append(minute).toString() : String.valueOf(minute);
		int second = cal.get(Calendar.SECOND);
		String secondStr = second < 10 ? new StringBuffer("0").append(second).toString() : String.valueOf(second);
		//2021-12-14T03:40:13.558Z
		UTCTimeBuffer.append(year).append("-").append(month).append("-").append(day);
		UTCTimeBuffer.append("T").append(hourStr).append(":").append(minuteStr).append(":").append(secondStr).append(".558Z");
		return UTCTimeBuffer.toString();

	}


	public void systemCheck() {
		Long startTime = System.currentTimeMillis();
		Set<String> alarmHosts = new HashSet<>();
		try {
			String utcStr = getUTC();
			SearchRequest searchRequest = new SearchRequest(index);
			searchRequest.searchType(SearchType.QUERY_THEN_FETCH);
			String[] includes = {"system.filesystem.used.pct", "system.filesystem.used.bytes", "host.hostname"};
			SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
			RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("@timestamp")
				.gte(utcStr);
			final BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
			boolQueryBuilder.must(QueryBuilders.matchQuery("metricset.name", "filesystem"));
			boolQueryBuilder.must(QueryBuilders.matchQuery("system.filesystem.mount_point", "/"));

			searchSourceBuilder.query(rangeQueryBuilder);
			searchSourceBuilder.query(boolQueryBuilder);

			searchSourceBuilder.fetchSource(includes, new String[]{});
			searchSourceBuilder.from(0);
			searchSourceBuilder.size(100);
			searchSourceBuilder.sort("@timestamp", SortOrder.DESC);

			searchRequest.source(searchSourceBuilder);

//			RestHighLevelClient client = restHighLevelClient;
			SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
			// 搜索结果
			SearchHits hits = searchResponse.getHits();
			TotalHits totalHits = hits.getTotalHits();
//			System.out.println("查询到的总记录数:" + totalHits.value);
			// 得到的匹配度高的文档
			SearchHit[] searchHits = hits.getHits();
			int count = 1;
			for (SearchHit hit : searchHits) {
				Map<String, Object> sourceMap = hit.getSourceAsMap();
				Double pct = 0.0;
				String hostName = null;
				for (String key : sourceMap.keySet()) {
					if ("system".equals(key)) {

						HashMap<String, Object> sourceMap1 = (HashMap<String, Object>) sourceMap.get(key);
						HashMap<String, Object> sourceMap2 = (HashMap<String, Object>) sourceMap1.get("filesystem");
						HashMap<String, Object> sourceMap3 = (HashMap<String, Object>) sourceMap2.get("used");
						try {
							pct = (Double) sourceMap3.get("pct");
						} catch (Exception e2) {
//							e2.printStackTrace();
						}
						count += 1;
					} else if ("host".equals(key)) {
						HashMap<String, Object> sourceMap1 = (HashMap<String, Object>) sourceMap.get(key);
						hostName = (String) sourceMap1.get("hostname");
					}

				}
				if (pct > alarmRate) {
					if (null != hostName) {
						alarmHosts.add(hostName);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
		} finally {
			if (alarmHosts.size() > 0) {
				for (String hostName : alarmHosts) {
					DingUtil.sendMsg("!!! 监控到当前host磁盘占用超过阈值：", hostName);
				}

			}
			log.info("systemCheckTask-end-:{}", System.currentTimeMillis() - startTime);
		}
	}

}



